package com.hog.service.common;

import org.apache.ibatis.session.RowBounds;
import tk.mybatis.mapper.entity.Example;

import java.util.List;

/**
 * Service 基类
 *
 * @author 唐先森
 * @date 2018年03月29日
 * @since JDK 1.7
 */
public interface IBaseService<T> {
    /**
     * 保存一个实体，null的属性也会保存，不会使用数据库默认值
     *
     * @param entity
     * @return
     */
    int insert(T entity);

    /**
     * 保存一个实体，null的属性不会保存，会使用数据库默认值
     *
     * @param entity
     * @return
     */
    int insertSelective(T entity);

    /**
     * 根据主键 "id" 是否有值来判断新增或更新
     *
     * @param entity
     * @return
     */
    int saveOrUpdate(T entity);

    /**
     * 批量插入，无法返回count数量，通过设置mybatis的session运行模式为ExecutorType.BATCH实现批量提交
     *
     * @param data
     */
    void insertBatch(List<T> data);

    /**
     * 根据实体属性作为条件进行删除，查询条件使用等号
     *
     * @param entity
     * @return
     */
    int delete(T entity);

    /**
     * 根据Example条件删除数据
     *
     * @param example
     * @return
     */
    int deleteByExample(Example example);

    /**
     * 根据主键字段进行删除，方法参数必须包含完整的主键属性
     *
     * @param key
     * @return
     */
    int deleteByPrimaryKey(Object key);

    /**
     * 根据Example条件更新实体`record`包含的全部属性，null值会被更新
     *
     * @param entity
     * @param example
     * @return
     */
    int updateByExample(T entity, Example example);

    /**
     * 根据Example条件更新实体`record`包含的不是null的属性值
     *
     * @param entity
     * @param example
     * @return
     */
    int updateByExampleSelective(T entity, Example example);

    /**
     * 根据主键更新实体全部字段，null值会被更新
     *
     * @param entity
     * @return
     */
    int updateByPrimaryKey(T entity);

    /**
     * 根据主键更新属性不为null的值
     *
     * @param entity
     * @return
     */
    int updateByPrimaryKeySelective(T entity);

    /**
     * 批量插入，调用updateByPrimaryKey
     *
     * @param data
     */
    void updateBatch(List<T> data);

    /**
     * 根据实体中的属性值进行查询，查询条件使用等号
     *
     * @param entity
     * @return
     */
    List<T> select(T entity);

    /**
     * 查询全部结果
     *
     * @return
     */
    List<T> selectAll();

    /**
     * 根据Example条件进行查询
     *
     * @param example
     * @return
     */
    List<T> selectByExample(Example example);

    /**
     * 根据example条件和RowBounds进行分页查询
     *
     * @param example
     * @param rowBounds
     * @return
     */
    List<T> selectByExampleAndRowBounds(Example example, RowBounds rowBounds);

    /**
     * 根据实体属性和RowBounds进行分页查询
     *
     * @param entity
     * @param rowBounds
     * @return
     */
    List<T> selectByRowBounds(T entity, RowBounds rowBounds);

    /**
     * 根据主键字段进行查询，方法参数必须包含完整的主键属性，查询条件使用等号
     *
     * @param key
     * @return
     */
    T selectByPrimaryKey(Object key);

    /**
     * 根据实体中的属性查询总数，查询条件使用等号
     *
     * @param entity
     * @return
     */
    int selectCount(T entity);

    /**
     * 根据Example条件进行查询总数
     *
     * @param example
     * @return
     */
    int selectCountByExample(Example example);

    /**
     * 根据实体中的属性进行查询，只能有一个返回值，有多个结果是抛出异常，查询条件使用等号
     *
     * @param entity
     * @return
     */
    T selectOne(T entity);

    /**
     * 根据实体中的属性值进行查询，查询条件使用等号，支持分页
     *
     * @param entity
     * @param pageNum
     * @param pageSize
     * @return
     */
    List<T> selectByPage(T entity, int pageNum, int pageSize);

    /**
     * 查询全部结果，支持分页
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    List<T> selectAllByPage(int pageNum, int pageSize);

    /**
     * 根据Example条件进行查询，支持分页
     *
     * @param example
     * @param pageNum
     * @param pageSize
     * @return
     */
    List<T> selectByExampleAndPage(Example example, int pageNum, int pageSize);
}